﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

public class Savegame
{
    public delegate void SavegameLoadedEventHandler(object sender, SavegameLoadedEventArgs e);

    private int checkpoint;
    private CurrentPowerup currentPowerup;
    private int level;
    private int score;
    private double time;

    public Savegame(int checkpoint, int levelId, double time, int score)
    {
        this.checkpoint = checkpoint;
        this.level = levelId;
        this.score = score;
        this.time = time;
    }

    public Savegame(int checkpoint, string levelName, double time, int score)
    {
        this.checkpoint = checkpoint;
        this.level = AllLevels.GetLevelIdByName(levelName);
        this.score = score;
        this.time = time;
    }

    public static event SavegameLoadedEventHandler OnSavegameLoaded;

    public void Save()
    {
        if (!Directory.Exists("Savegames"))
            Directory.CreateDirectory("Savegames");

        using (FileStream fs = new FileStream(string.Format(@"Savegames/{0}.sav", Player.Name), FileMode.Create))
        {
            using (BinaryWriter bw = new BinaryWriter(fs))
            {
                bw.Write(this.level);
                bw.Write(this.checkpoint);
                bw.Write((int)Player.Powerup.powerup);
                bw.Write(this.time);
                bw.Write(this.score);
                bw.Write(Player.HitPoints);
                bw.Write(Player.Energy);
                bw.Write((double)Player.StartPosition.x);
                bw.Write((double)Player.StartPosition.y);
                bw.Write((double)Player.StartPosition.z);
            }
        }
    }

    private SavegameLoadedEventArgs Load(string playerName)
    {
        SavegameLoadedEventArgs e;

        DirectoryInfo directoryInfo = new DirectoryInfo("Savegames");
        if (!directoryInfo.Exists) return null;

        FileInfo fileInfo = new FileInfo(@"Savegames/" + playerName);
        if (!fileInfo.Exists) return null;

        using (FileStream fs = new FileStream(string.Format(@"Savegames/{0}", playerName), FileMode.Open))
        {
            using (BinaryReader br = new BinaryReader(fs))
            {
                this.level = br.ReadInt32();
                this.checkpoint = br.ReadInt32();
                this.currentPowerup = (CurrentPowerup)br.ReadInt32();
                this.time = br.ReadDouble();
                this.score = br.ReadInt32();

                e = new SavegameLoadedEventArgs
                    {
                        PlayerHitPoints = br.ReadInt32(),
                        PlayerEngergy = br.ReadInt32(),
                        PlayerStartPosition = new Vector3
                            {
                                x = (float)br.ReadDouble(),
                                y = (float)br.ReadDouble(),
                                z = (float)br.ReadDouble()
                            },
                        PlayerName = playerName.Remove(playerName.Length - 4, 4),
                        Checkpoint = this.checkpoint,
                        Level = this.level,
                        Powerup = this.currentPowerup,
                        Time = this.time,
                        SaveTime = fileInfo.LastWriteTime
                    };

                if (OnSavegameLoaded != null)
                    OnSavegameLoaded(this, e);
            }
        }
        return e;
    }

    public List<string> LoadSaveGameList()
    {
        DirectoryInfo di = new DirectoryInfo("Savegames");

        return di.GetFiles().Select(file => file.Name.Remove(file.Name.Length - 4, 4)).ToList();
    }

    public SavegameLoadedEventArgs LoadSelectedSavegameDetails(int selected)
    {
        DirectoryInfo directoryInfo = new DirectoryInfo("Savegames");

        return directoryInfo.Exists ? Load(directoryInfo.GetFiles()[selected].Name) : null;
    }
}

public class SavegameLoadedEventArgs : EventArgs
{
    public int Checkpoint;
    public int Level;
    public int PlayerEngergy;
    public int PlayerHitPoints;
    public string PlayerName;
    public Vector3 PlayerStartPosition;
    public CurrentPowerup Powerup;
    public DateTime SaveTime;
    public double Time;
}